/*LICENSE_BEGIN
 * ******************************************************************
 * Copyright 2006 by the Dainamite Robocup-Team at the
 * DAI-Labor, TU-Berlin (www.dai-labor.de)
 * 
 * Members of Dainamite are:
 * Holger Endert
 * Robert Wetzker
 * Thomas Karbe
 * Axel Heßler
 * Philippe Bütter
 * Felix Brossmann
 * 
 * Licensed under the GNU GPL (General Public License) Free Software 
 * License, Version 2. You may use this file only in compliance with 
 * the License. You may obtain a copy of the License at:
 * 
 * http://www.fsf.org/licensing/licenses/gpl.txt
 * ******************************************************************
LICENSE_END*/
package robocup.component.actionfactories;

import robocup.component.WorldModel;
import robocup.component.actions.Action;
import robocup.component.actions.ChangeViewModeAction;
import robocup.component.actions.TurnNeckAction;
import robocup.component.geometry.Vektor;
import robocup.component.tactics.AbstractState.STATES;
import robocup.component.worldobjects.DynamicObject;
import robocup.component.worldobjects.Player;
import robocup.component.worldobjects.Player.RELATIVE;

/**
 * A factory for turn-neck actions. Thsi provides some methods to easiliy
 * select the desired looking direction. Per default, it uses the 
 * <code>NeckRotator</code>, which determines the next view-angle by some
 * sort of importance for certain objects/distances, specified independently 
 * for each state.
 */
public class TurnNeckActionFactory {

	/**
	 * Returns the best action for turning the neck.
	 * 
	 * @param world -
	 *            the world model
	 * @param state -
	 *            the state
	 * @param mainAction -
	 *            main action
	 * @param viewModeAction -
	 *            view mode action
	 * @return the best action for turning the neck
	 */
	public static TurnNeckAction getAction(WorldModel world, STATES state,
			Action mainAction, ChangeViewModeAction viewModeAction) {

		return new TurnNeckAction(world.getBestTurnNeckAngle(mainAction,
				viewModeAction, state));
	}

	/**
	 * returns the best action for turning the neck.
	 * 
	 * @param world -
	 *            the world model
	 * @param state -
	 *            the state
	 * @param mainAction -
	 *            main action
	 * @param viewModeAction -
	 *            view mode action
	 * @param preferred
	 *            an array of size 23. 0-10 are own players, 11 -21 are
	 *            opponents and 22 is the ball a value of 0 means that the
	 *            player should be handled normal. 1 means, to see him always
	 *            and -1 means to ignore him
	 * @return the tn-action
	 */
	public static TurnNeckAction getAction(WorldModel world, STATES state,
			Action mainAction, ChangeViewModeAction viewModeAction,
			double[] preferred) {

		return new TurnNeckAction(world.getBestTurnNeckAngle(mainAction,
				viewModeAction, state, preferred));
	}

	/**
	 * returns the best action for turning the neck.
	 * 
	 * @param world -
	 *            the world model
	 * @param state -
	 *            the state
	 * @param mainAction -
	 *            main action
	 * @param viewModeAction -
	 *            view mode action
	 * @param preferredObject
	 *            the object that should be seen always
	 * @return the tn-action
	 */
	public static TurnNeckAction getAction(WorldModel world, STATES state,
			Action mainAction, ChangeViewModeAction viewModeAction,
			DynamicObject preferredObject) {

		return new TurnNeckAction(world.getBestTurnNeckAngle(mainAction,
				viewModeAction, state, preferredObject));
	}

	/**
   * Returns a turn neck action to watch the given point, if possible.
   * 
	 * @param p
	 * @param point
	 * @return watch to point if possible
	 */
	public static TurnNeckAction watchPoint(Player p, Vektor point) {
		double ang = p.getAngleRel(point, RELATIVE.TO_HEAD);
		if (Math.abs(ang) <= 90) {
      return new TurnNeckAction(ang);
    }
		return null;
	}
  
  
}
